package ru.stork.vasilisa.core

import ru.stork.vasilisa.lang
import ru.stork.vasilisa.model
import com.yelbota.util.{$lazy, Lazy}
import model.{ImportDef, Namespace}

class NamespaceImpl(val manager: SourceManager,
                    override val imports: List[ImportDef],
                    override val local: List[String],
                    val privateDeclarations:Map[String, Lazy[model.VasilisaType]])
  extends Namespace {

  def configure(imports: List[ImportDef], local: NsDef): Namespace =
    new NamespaceImpl(manager, imports, local, Map())

  def addPrivateDeclarations(value: Map[String, Lazy[model.VasilisaType]]): Namespace =
    new NamespaceImpl(manager, imports, local, value ++ privateDeclarations)

  def findTrait(name: String): Option[Lazy[model.VasilisaType]] = {

    def fromSource(x: String) = $lazy {
      val node = lang.Ast.fromFile(x)
      model.VasilisaType.fromNode(configure(List(), local), node)
    }

    // First lets try to find trait in private declarations
    privateDeclarations.get(name) match {
      // FIXME bad code
      case None => {
        // Ok. Lets try to find in local package
        manager.getSourceInPackage(local, name) match {
          case Some(x) => Some(fromSource(x))
          case None => {
            // Find in imports
            imports.find(x => x.name == name) match {
              case Some(x) => manager.getSourceInPackage(x.pkg, name) match {
                case Some(x) => Some(fromSource(x))
                case None => None
              }
              case None => None
            }
          }
        }
      }
      case x => x
    }
  }

}